<template>
  <div class="productInfo">
    <div class="tableWrap">
      <c-table
        ref="productInfo"
        :data="tableData"
        :columns="tableColumns"
        :rowKey="
          (record, index) => {
            return index;
          }
        "
        :showPage="false"
        bordered
        size="small"
        :showHeader="false"
        :rowClassName="
          () => {
            return 'inputRow';
          }
        "
        @mouseenter="rowMouseenter"
        @mouseleave="rowMouseleave"
      >
        <!-- 其他列输入框  -->
        <template
          :slot="item.scopedSlots.customRender"
          slot-scope="scope"
          v-for="item in tableColumnsSlot"
        >
          <div :key="item.scopedSlots.customRender">
            <a-auto-complete
              v-model.trim="scope.row[item.scopedSlots.customRender]"
              :dataSource="searchList[item.scopedSlots.customRender]"
              class="input-auto-complete"
              :dropdownMatchSelectWidth="false"
              :placeholder="'请输入' + item.title"
              @search="
                val => {
                  searchKey(val, item.scopedSlots.customRender);
                }
              "
            >
            </a-auto-complete>
          </div>
        </template>
        <template v-slot:amount="{ row }">
          <span v-if="$route.name === 'quotationUpdate'">{{ row.amount }}</span>
          <a-input-number
            v-model.trim="row.amount"
            placeholder="必填"
            v-else
          ></a-input-number>
        </template>
        <template v-slot:premium="{ row }">
          <span v-if="$route.name === 'quotationUpdate'"
            >{{ row.premium }}
          </span>
          <a-input-number
            v-model.trim="row.premium"
            placeholder="必填"
            :precision="0"
            v-else
          ></a-input-number>
        </template>
        <template v-slot:price="{ row }">
          <span v-if="$route.name === 'quotationUpdate'">{{ row.price }}</span>
          <a-input-number
            v-model.trim="row.price"
            placeholder="必填"
            v-else
          ></a-input-number>
        </template>
        <template slot="handle" slot-scope="{ row, idx }">
          <div class="handle">
            <a-icon
              type="plus"
              v-if="idx === 0"
              class="primary fontw"
              @click="addRow"
            ></a-icon>
            <a-icon
              type="minus"
              v-else
              class="danger fontw"
              @click="delRow(idx)"
            ></a-icon>
          </div>
        </template>
      </c-table>
      <Tooltip
        :visible="tooltipVisible"
        :originalData="originalData"
        :row="rowMouseenterData"
        v-if="$route.name === 'quotationUpdate'"
      />
    </div>
    <div class="importTableData flex" v-if="$route.name !== 'quotationUpdate'">
      <div class="text">输入太麻烦？Excel批量导入！</div>
      <download-excel
        :data="excel_data"
        :fields="excel_titles"
        worksheet="My Worksheet"
        type="xlsx"
        :name="`发布报价模板(${priceType === 1 ? '点价' : '确定价'})`"
      >
        <c-button type="link">下载模板</c-button>
      </download-excel>
      <ImportExcel @change="importTable" />
    </div>
    <!-- 补充仓库弹窗 -->
    <c-modal
      v-model="addWarehouseVisible"
      title="仓库补充"
      centered
      @ok="addWarehouse"
      destroyOnClose
    >
      <div class="addWarehouse">
        <a-form-model
          :model="addWarehouseForm"
          ref="addWarehouseForm"
          :labelCol="{ style: { width: '100px' } }"
        >
          <template v-for="(item, idx) in addWarehouseForm.items">
            <a-divider orientation="left" :key="idx"
              >仓库{{ idx + 1 }}</a-divider
            >
            <a-form-model-item label="仓库简称" :key="'shortName' + idx"
              >{{ item.shortName }}
            </a-form-model-item>
            <a-form-model-item
              :key="'name' + idx"
              label="仓库全称"
              :prop="'items.' + idx + '.name'"
              :rules="{
                required: true,
                message: '请输入仓库全称',
                trigger: 'change'
              }"
            >
              <a-input
                v-model="item.name"
                placeholder="请输入仓库全称"
              ></a-input>
            </a-form-model-item>
            <a-form-model-item
              :key="'cityId' + idx"
              label="所在省市"
              :prop="'items.' + idx + '.cityId'"
              :rules="{
                required: true,
                message: '请选择所在省市',
                trigger: 'change'
              }"
            >
              <c-city v-model="item.cityId" />
            </a-form-model-item>
            <a-form-model-item
              :key="'address' + idx"
              label="具体地址"
              :prop="'items.' + idx + '.address'"
              :rules="{
                required: true,
                message: '请输入具体地址',
                trigger: 'change'
              }"
            >
              <a-textarea
                v-model="item.address"
                placeholder="请输入具体地址"
              ></a-textarea>
            </a-form-model-item>
          </template>
        </a-form-model>
      </div>
    </c-modal>
  </div>
</template>

<script>
import { getcompanywarehouses, addwarehousebatch } from "@/api/warehouse";
import { getcategoryattr } from "@/api/quotation";
import { debounce } from "@/util/common";
import { findIndex } from "lodash";
import ImportExcel from "./importExcel";
import JsonExcel from "vue-json-excel";
import { uniq } from "lodash";
import Tooltip from "./tooltip";
import quotationDict from "@/dict/quotation";

const json_fields = {
  品牌: "brand",
  规格: "spec",
  材质: "material",
  其他: "other",
  仓库简称: "warehouseName",
  数量: "amount",
  升贴水: "premium"
};
const json_data = [
  {
    brand: "",
    spec: "",
    material: "",
    other: "",
    warehouseName: "",
    amount: "",
    premium: ""
  }
];

export default {
  components: {
    ImportExcel,
    downloadExcel: JsonExcel,
    Tooltip
  },
  props: {
    value: {
      type: Array
    },
    // 报价类型
    priceType: {
      type: Number,
      default: 1
    },
    // 选择的品种，用于查询商品属性
    categoryCode: {
      type: Array,
      default: () => {
        return [];
      }
    },
    originalData: {
      type: Array
    }
  },
  data() {
    return {
      json_data,
      json_fields,
      // 补全列表
      searchList: {
        brand: [], // 品牌
        spec: [], // 规格
        material: [], // 材质
        other: [], // 其他
        warehouseName: [] // 仓库
      },
      initSearchList: {
        brand: [], // 品牌
        spec: [], // 规格
        material: [], // 材质
        other: [], // 其他
        warehouseName: [] // 仓库
      },
      allWarehouses: [], // 原始所有仓库
      addWarehouseVisible: false, // 补充仓库弹窗显隐
      addWarehouseForm: {
        // 新增仓库列表
        items: []
      },
      rowMouseenterData: undefined,
      tooltipVisible: false
    };
  },
  computed: {
    tableData: {
      get() {
        return this.value;
      },
      set(n) {
        this.$emit("input", n);
      }
    },
    tableColumns() {
      let data = [
        {
          title: "品牌",
          dataSource: "brandSearchList",
          scopedSlots: { customRender: "brand" }
        },
        {
          title: "规格",
          dataSource: "specSearchList",
          scopedSlots: { customRender: "spec" }
        },
        {
          title: "材质",
          dataSource: "materialSearchList",
          scopedSlots: { customRender: "material" }
        },
        {
          title: "其他",
          dataSource: "otherSearchList",
          scopedSlots: { customRender: "other" }
        },
        {
          title: "仓库简称",
          scopedSlots: { customRender: "warehouseName" }
        },
        {
          title: "数量",
          scopedSlots: { customRender: "amount" }
        },
        {
          title:
            this.priceType === quotationDict.priceType.pricing.value
              ? "升贴水"
              : "价格",
          scopedSlots: {
            customRender:
              this.priceType === quotationDict.priceType.pricing.value
                ? "premium"
                : "price"
          }
        },
        {
          title: "操作",
          align: "center",
          width: 50,
          hidden: this.$route.name === "quotationUpdate" ? true : false,
          scopedSlots: { customRender: "handle" }
        }
      ];
      return data;
    },
    tableColumnsSlot() {
      let columns = JSON.parse(JSON.stringify(this.tableColumns));
      columns.splice(-1, 1);
      return columns;
    },
    excel_titles() {
      let obj = {
        品牌: "brand",
        规格: "spec",
        材质: "material",
        其他: "other",
        仓库简称: "warehouseName",
        数量: "amount"
      };
      obj[this.priceType === 1 ? "升贴水" : "价格"] =
        this.priceType === 1 ? "premium" : "price";
      return obj;
    },
    excel_data() {
      let obj = {
        brand: "",
        spec: "",
        material: "",
        other: "",
        warehouseName: "",
        amount: ""
      };
      obj[this.priceType === 1 ? "premium" : "price"] = "";
      return [obj];
    }
  },
  watch: {
    categoryCode() {
      this.getAttrs();
    }
  },
  methods: {
    // 鼠标移入行
    rowMouseenter: debounce(function(data) {
      this.rowMouseenterData = data;
      this.tooltipVisible = true;
    }),
    // 鼠标移出行
    rowMouseleave: debounce(function() {
      this.tooltipVisible = false;
    }),
    // 获取商品属性
    getAttrs() {
      if (this.categoryCode && this.categoryCode.length !== 0) {
        getcategoryattr({
          categoryId: this.categoryCode[this.categoryCode.length - 1]
        }).then(res => {
          this.initSearchList.brand = this.searchList.brand = res
            .filter(i => i.categoryAttrType === 1)
            .map(i => i.attrValue);
          this.initSearchList.spec = this.searchList.spec = res
            .filter(i => i.categoryAttrType === 2)
            .map(i => i.attrValue);
          this.initSearchList.material = this.searchList.material = res
            .filter(i => i.categoryAttrType === 3)
            .map(i => i.attrValue);
          this.initSearchList.other = this.searchList.other = res
            .filter(i => i.categoryAttrType === 4)
            .map(i => i.attrValue);
        });
      }
    },
    // 提交仓库补充
    addWarehouse() {
      this.$refs.addWarehouseForm.validate(valid => {
        if (valid) {
          let params = JSON.parse(JSON.stringify(this.addWarehouseForm.items));
          params.forEach(i => {
            i.shortName = [i.shortName];
            i.cityId = i.cityId[1];
          });
          addwarehousebatch(params).then(() => {
            this.addWarehouseVisible = false;
            this.$message.success("操作成功");
            this.getAllWarehouses().then(() => {
              // 重新查询仓库对应的id进行替换
              let data = this.replaceWarehouseVal();
              this.$emit("addWarehouseSuccess", data);
            });
          });
        }
      });
    },
    // 仓库输入框失去焦点时的回调
    checkWarehouse() {
      // 检查商品信息中不匹配的仓库
      return new Promise((reslove, reject) => {
        let res = [];
        let warehouses = uniq(this.tableData.map(i => i.warehouseName)); // 商品信息中仓库
        // let shortNames = this.initSearchList.warehouseName.map(i => i.shortName); // 初始仓库搜索列表中仓库简称
        for (let i = 0; i < warehouses.length; i++) {
          if (this.initSearchList.warehouseName.indexOf(warehouses[i]) === -1)
            res.push(warehouses[i]); // 匹配不到的仓库简称push到res
        }
        if (res.length === 0) {
          // res长度为0说明没有匹配不到的仓库简称
          let data = this.replaceWarehouseVal();
          reslove(data);
        } else {
          reject();
          this.addWarehouseVisible = true;
          // 重置新增仓库列表
          this.addWarehouseForm.items = [];
          res.forEach(item => {
            this.addWarehouseForm.items.push({
              shortName: item,
              name: undefined,
              cityId: undefined,
              address: undefined
            });
          });
        }
      });
    },
    // 仓库简称替换成仓库id
    replaceWarehouseVal() {
      let tableData = JSON.parse(JSON.stringify(this.tableData));
      tableData.forEach(item => {
        let idx = findIndex(this.allWarehouses, [
          "shortName",
          item.warehouseName
        ]);
        item.warehouseId = this.allWarehouses[idx].id;
      });
      return tableData;
    },
    // 搜索输入值对应的可选项
    searchKey: debounce(function(val, name) {
      if (name !== "amount" && name !== "premium" && name !== "price") {
        // 数量、升贴水、价格没有参考项
        let res = [];
        this.initSearchList[name].forEach(item => {
          if (item.includes(val.trim())) {
            res.push(item);
          }
        });
        this.$set(this.searchList, name, res);
      }
    }),
    importTable(data) {
      this.tableData = data;
    },
    // 新增一行
    addRow() {
      this.$emit("addRow");
    },
    // 删除一行
    delRow(idx) {
      this.$emit("delRow", idx);
    },
    // 获取该公司的所有仓库
    getAllWarehouses() {
      return new Promise(reslove => {
        getcompanywarehouses().then(res => {
          this.allWarehouses = res; // 存储原始数据用于查询仓库id
          let data = res.map(i => i.shortName);
          this.initSearchList.warehouseName = data;
          this.searchList.warehouseName = data;
          reslove();
        });
      });
    },
    // 是否存在相同商品或信息不完整
    isSameGoods() {
      let _this = this;
      return new Promise((resolve, reject) => {
        let rowMap = new Map();
        let goodsData = _this.tableData;
        let brandCol = [];
        let specCol = [];
        let materialCol = [];
        let otherCol = [];
        let warehouseCol = [];
        for (let row of goodsData) {
          // 如果row对应的列数据为undefined的话,默认赋值为N
          let brand = row.brand == undefined ? "" : (row.brand + " ").trim();
          let spec = row.spec == undefined ? "" : (row.spec + " ").trim();
          let material =
            row.material == undefined ? "" : (row.material + " ").trim();
          let other = row.other == undefined ? "" : (row.other + " ").trim();
          let warehouseName =
            row.warehouseName == undefined
              ? ""
              : (row.warehouseName + " ").trim();
          let key = `${brand}&${spec}&${material}&${other}&${warehouseName}`;
          rowMap.set(key);
          brand == "" ? "" : brandCol.push(brand);
          spec == "" ? "" : specCol.push(spec);
          material == "" ? "" : materialCol.push(material);
          other == "" ? "" : otherCol.push(other);
          warehouseName == "" ? "" : warehouseCol.push(warehouseName);
        }
        let length = goodsData.length;
        let rowSize = rowMap.size;
        let brandColSize = brandCol.length;
        let specColSize = specCol.length;
        let materialColSize = materialCol.length;
        let otherColSize = otherCol.length;
        let warehouseColSize = warehouseCol.length;
        if (length > rowSize) {
          this.$message.warning("不能有重复商品");
          return reject();
        }
        if (brandColSize > 0 && brandColSize < length) {
          this.$message.warning("请填写完整全部品牌信息");
          return reject();
        }
        if (specColSize > 0 && specColSize < length) {
          this.$message.warning("请填写完整全部规格信息");
          return reject();
        }
        if (materialColSize > 0 && materialColSize < length) {
          this.$message.warning("请填写完整全部材质信息");
          return reject();
        }
        if (otherColSize > 0 && otherColSize < length) {
          this.$message.warning("请填写完整全部其他信息");
          return reject();
        }
        if (warehouseColSize > 0 && warehouseColSize < length) {
          this.$message.warning("请填写完整全部仓库信息");
          return reject();
        }
        resolve();
      });
    },
    // 仓库升贴水价格是否填写完整
    checkWarehousePremium() {
      return new Promise((resolve, reject) => {
        let isUpdate = this.$route.name === "quotationUpdate";
        // 编辑时，不需要校验升贴水和数量
        // 检查有无不通过的商品信息
        // 升贴水、价格
        let premiums =
          this.priceType === 1
            ? this.tableData.filter(i => !isUpdate && !i.premium)
            : this.tableData.filter(i => !isUpdate && !i.price);

        // 仓库
        let warehouses = this.tableData.filter(i => !i.warehouseName);
        // 数量
        let amounts = this.tableData.filter(i => !isUpdate && !i.amount);
        if (
          premiums.length !== 0 ||
          warehouses.length !== 0 ||
          amounts.length !== 0
        ) {
          // 升贴水/价格、仓库必填
          let msg_premiums = `${
            premiums.length !== 0
              ? this.priceType === 1
                ? "升贴水"
                : "价格"
              : ""
          }`;
          let space = `${
            premiums.length !== 0 && warehouses.length !== 0 ? "、" : ""
          }`;
          let msg_warehouses = `${warehouses.length !== 0 ? "仓库" : ""}`;
          let msg_amounts = `${amounts.length !== 0 ? "数量" : ""}`;
          // 商品信息不通过，弹窗提示完善商品信息
          let h = this.$createElement;
          this.$message.warning(
            h("span", [
              "请补充完整商品信息中的",
              h(
                "span",
                {
                  style: {
                    // color: "red"
                  }
                },
                msg_warehouses + space + msg_amounts + space + msg_premiums
              )
            ])
          );
          reject();
        } else {
          resolve();
        }
      });
    }
  },
  created() {
    this.getAllWarehouses();
    if (this.$route.name === "quotationUpdate") {
      this.getAttrs();
    }
  }
};
</script>

<style lang="scss" scoped>
.productInfo {
  .tableWrap {
    position: relative;
  }
  .c-table {
    overflow: auto;
    ::v-deep .ant-input,
    .ant-input-number,
    .ant-select {
      border: 0;
      padding: 0;
      width: 100% !important;
    }
    ::v-deep .ant-input-number .ant-input-number-input {
      padding: 0;
    }
    ::v-deep .ant-input-number-focused {
      box-shadow: none !important;
    }
  }
  ::v-deep .c-table .inputRow {
    td {
      padding-top: 0 !important;
      padding-bottom: 0 !important;
      .c-button {
        font-size: 10px;
      }
    }
  }
  .importTableData {
    line-height: 32px;
    margin-top: 6px;
  }
  .handle {
    display: flex;
    justify-content: center;
    i {
      font-size: 20px;
      cursor: pointer;
    }
  }
  // 输入框内容超出省略
  ::v-deep .input-auto-complete input {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }
  .addWarehouse {
    max-height: 80vh;
    overflow-y: auto;
    .ant-form-item {
      // width: 350px;
      // margin: 0 auto 24px;
      textarea.ant-input {
        width: 100%;
      }
    }
  }
}
</style>
